/**
 * 
 */
package org.ejc.struts.search;

import java.util.Collection;
import java.util.List;
import java.util.Locale;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.actions.DispatchAction;
import org.ejc.api.registration.RegistrationAPIUtil;
import org.ejc.datatype.executive.ExecutiveSearchCriteria;
import org.ejc.datatype.registrant.RegistrantSearchCriteria;
import org.ejc.session.EJCSession;
import org.ejc.tech.combo.ComboConstants;
import org.ejc.tech.combo.ComboMgr;

/**
 * @author Brian Boyle
 * @struts.action path="/struts/search/searchRegistrantsAction" scope="request"
 *                parameter="methodToCall" name="searchRegistrantsForm"
 *                validate="false"
 *                input="/struts/search/searchRegistrants.jsp"
 * 
 * @struts.action-forward name="preSearchSuccess" path="/struts/search/searchRegistrants.jsp"
 * @struts.action-forward name="searchSuccess" path="/struts/search/searchRegistrantsAction.do?methodToCall=preSearchPaging"
 * 
 */
public class SearchRegistrantsAction extends DispatchAction implements ComboConstants{

	private static final int resultSetIndex = 0;
	private static final int resultSetSize = 100; 
	
	/* (non-Javadoc)
	 * @see org.apache.struts.actions.DispatchAction#execute(org.apache.struts.action.ActionMapping, org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
	 */
	public final ActionForward preSearch(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception 
	{
		loadPreSearchDetails(request, form);
		//Hide the navigation initially
		request.setAttribute("hideNavigation", true);
		return mapping.findForward("preSearchSuccess");
	}
	
	private void loadPreSearchDetails( HttpServletRequest request, ActionForm form){
		HttpSession session = request.getSession();
		EJCSession ejcSession = (EJCSession) session.getAttribute("ejcSession");
		loadComboBoxes(request);
		ejcSession.setCurrentAction("Search Guests");
		SearchRegistrantsForm searchForm = (SearchRegistrantsForm)form;
		request.setAttribute("advancedSearch", searchForm.getAdvancedSearch());
	}
	
	public final ActionForward preSearchPaging(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception 
	{
		loadPreSearchDetails(request, form);
		return mapping.findForward("preSearchSuccess");
	}

	public final ActionForward searchGuests(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception
	{
		HttpSession session = request.getSession();
		EJCSession ejcSession = (EJCSession) session.getAttribute("ejcSession");
		SearchRegistrantsForm searchForm = (SearchRegistrantsForm) form;
		RegistrantSearchCriteria searchCriteria = createSearchCriteria(searchForm);
		List listORegs = RegistrationAPIUtil.getLocalHome().create().searchRegistrants(searchCriteria, resultSetIndex, resultSetSize);
		request.setAttribute("listOfRegs", listORegs);
		request.setAttribute("advancedSearch", searchForm.getAdvancedSearch());
		//Set up attributes needed for paging
		ejcSession.setResultIndex(resultSetIndex);
		ejcSession.setResultSize(resultSetSize);
		ejcSession.setCriteria(searchCriteria);
		request.setAttribute("initialSearch", true);
		if(listORegs.size() < resultSetSize){
			request.setAttribute("noNext", true);
		}
		if(ejcSession.getResultIndex() == 0){
			request.setAttribute("noPrevious", true);
		}
		return mapping.findForward("searchSuccess");
	}
	
	public void searchGuestsPaging(HttpServletRequest request, int resultSetSize, int resultIndex) throws Exception
	{
		HttpSession session = request.getSession();
		EJCSession ejcSession = (EJCSession) session.getAttribute("ejcSession");
		RegistrantSearchCriteria searchCriteria = (RegistrantSearchCriteria) ejcSession.getCriteria();
		List listORegs = RegistrationAPIUtil.getLocalHome().create().searchRegistrants(searchCriteria, resultIndex, resultSetSize);
		request.setAttribute("listOfRegs", listORegs);
		ejcSession.setResultIndex(resultIndex);
		ejcSession.setResultSize(resultSetSize);
		//If the size of the resultSet is less than or equal to the max result then do not show the NEXT button
		if(listORegs.size() < resultSetSize){
			request.setAttribute("noNext", true);
		}
		if(ejcSession.getResultIndex() == 0){
			request.setAttribute("noPrevious", true);
		}
	}
	
	/**
	 * Search the next results in the resultSet
	 * @param mapping
	 * @param form
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception
	 */
	public final ActionForward searchNext(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception
	{
		HttpSession session = request.getSession();
		EJCSession ejcSession = (EJCSession) session.getAttribute("ejcSession");
		int minResult = ejcSession.getResultIndex() + resultSetSize;
		int	maxResult = ejcSession.getResultSize();
		searchGuestsPaging(request, maxResult, minResult);
		return mapping.findForward("searchSuccess");
	}
	
	/**
	 * Search the previous results in the resultSet
	 * @param mapping
	 * @param form
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception
	 */
	public final ActionForward searchPrevious(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception
	{
		HttpSession session = request.getSession();
		EJCSession ejcSession = (EJCSession) session.getAttribute("ejcSession");
		int minResult = ejcSession.getResultIndex() - resultSetSize;
		int	maxResult = ejcSession.getResultSize();
		searchGuestsPaging(request, maxResult, minResult);
		return mapping.findForward("searchSuccess");
	}
	
	private void loadComboBoxes(HttpServletRequest request){
		request.setAttribute("countries",getCountryListing(request.getLocale()));
		request.setAttribute("registrantTypes",getRegistrantTypesListing(request.getLocale()));
		request.setAttribute("accomodationTypes",getAccomodationTypesListing(request.getLocale()));
		request.setAttribute("registrantStatusTypes",getAccomodationTypesListing(request.getLocale()));
	}
	
	private RegistrantSearchCriteria createSearchCriteria(SearchRegistrantsForm form)
	{
		RegistrantSearchCriteria searchCriteria = new RegistrantSearchCriteria();
		if(form.getAdvancedSearch()){
			searchCriteria.setAdvancedSearch(form.getAdvancedSearch());
			searchCriteria.setAccommodationTypeId(form.getAccomodationTypeId());
			searchCriteria.setCountryId(form.getCountryCodeCountryId());
			searchCriteria.setFirstName(form.getFirstName());
			searchCriteria.setAdvLastName(form.getAdvLastName());
			searchCriteria.setLengthOfStay(form.getLengthOfStay());
			searchCriteria.setPreRegistration(form.getPreRegistration());
			searchCriteria.setAdvPreRegCode(form.getAdvPreRegCode());
			//searchCriteria.setRegStatus(form.get)
			searchCriteria.setRegTypeId(form.getRegistrantTypeId());
			searchCriteria.setStatusId(form.getStatusId());
			searchCriteria.setNotes(form.getNotes());
			
		}
		searchCriteria.setLastName(form.getLastName());
		searchCriteria.setPreRegCode(form.getPreRegCode());
		return searchCriteria;
	}
	
	/**
	 * Retrieve a list of the countries
	 * @param locale The user locale
	 * @return List of countries
	 */
	private Collection getCountryListing(Locale locale){
		return ComboMgr.getInstance().getComboContents(COUNTRY,locale);
	}
	
	/**
	 * Retrieve a list of the RegistrantTypes
	 * @param locale The user locale
	 * @return List of RegistrantTypes
	 */
	private Collection getRegistrantTypesListing(Locale locale){
		return ComboMgr.getInstance().getComboContents(REGISTRANT_TYPE,locale);
	}
	
	/**
	 * Retrieve a list of the AccomodationTypes
	 * @param locale The user locale
	 * @return List of AccomodationTypes
	 */
	private Collection getAccomodationTypesListing(Locale locale){
		return ComboMgr.getInstance().getComboContents(ACCOMODATION_TYPE,locale);
	}
}
